package cn.jinjimi.framework.router;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;

import cn.jinjimi.app.bean.RouterConstants;
import cn.jinjimi.app.bean.RouterService;
import cn.jinjimi.base.util.StringUtils;
import cn.jinjimi.base.util.URLUtil;
import cn.jinjimi.app.AccountManager;
import cn.jinjimi.app.AppContext;
import cn.jinjimi.app.webview.utils.WebUtils;
import cn.jinjimi.app.bean.BundleKey;
import cn.jinjimi.app.modules.notify.notifications.PushDTO;
import cn.jinjimi.framework.router.impl.DirectRoute;
import cn.jinjimi.app.main.activity.LoginActivity;
import cn.jinjimi.app.main.activity.WebActivity;

import java.io.File;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhenhua
 */

public class RouterHelper {

    /**
     * 提供Notification设置跳转Intent
     *
     * @param context
     * @return
     */
    public static Intent[] getIntent(Context context, PushDTO notification) {

        if (notification == null) {
            return null;
        }

        String url = notification.getUrl();

        if (url == null)
            return null;

        URI uri = URLUtil.create(url);

        if (uri == null)
            return null;

        if (uri.getScheme() == null) {
            return null;
        }

        boolean isNativeLink = RouterService.ROUTER_HEADER.equalsIgnoreCase(uri.getScheme());

        if (uri.isAbsolute() && (isNativeLink
                || uri.getScheme().equalsIgnoreCase("http")
                || uri.getScheme().equalsIgnoreCase("https"))) {

            Intent route;

            //native link
            if (isNativeLink) {
                route = getNativeIntent(context, uri);
                if (route == null)
                    return null;
            }
            //http link
            else {
                route = new Intent(context, WebActivity.class);

                if (context instanceof AppContext) {
                    route.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                }
                route.putExtra(BundleKey.TYPE, 3);
                route.putExtra(BundleKey.LIMIT, isNeedLogin(notification) ? 1 : 0);
                route.putExtra(BundleKey.URL, url);
            }

            route.putExtra(BundleKey.PARAM_NOTIFICATION_ID, String.valueOf(notification.getFromSorce()));
            route.putExtra(BundleKey.PARAM_NOTIFICATION_TYPE, String.valueOf(notification.getType()));
            route.putExtra(BundleKey.PARAM_NOTIFICATION_TO, notification.getUrl());
            route.putExtra(BundleKey.PARAM_NOTIFICATION_FROM, notification.getSource());

            //need login ?
            return isNeedLogin(notification)
                    ? new Intent[]{new Intent(context, LoginActivity.class), route}
                    : new Intent[]{route};

        }

        return null;
    }

    /**
     * 通过第三方网页Schema打开app的路由处理
     *
     * @param context
     * @param uri
     * @return
     */
    public static Intent[] getIntent(Context context, Uri uri) {
        if (uri == null) {
            return null;
        }

        boolean isNativeLink = uri.getScheme().equalsIgnoreCase("cn.jinjimi");

        Intent route;

        //native link
        if (isNativeLink) {

            //http link
            if (uri.getHost().equals(RouterConstants.ROUTER_WEB)) {
                route = new Intent(context, WebActivity.class);

                String url = uri.getQueryParameter(RouterService.ROUTER_WEB_ROUTER);
                //兼容direct
                if (TextUtils.isEmpty(url)) {
                    url = uri.getQueryParameter(RouterService.ROUTER_WEB_ROUTER_DIRECT);
                }

                if (!WebUtils.isDomain(url)) {
                    return null;
                }

                route.putExtra(BundleKey.URL, url);
                return isNeedLogin(url)
                        ? new Intent[]{new Intent(context, LoginActivity.class), route}
                        : new Intent[]{route};
            }

            route = getNativeIntent(context, URLUtil.create(uri.toString()));
            if (route == null) {
                return null;
            }

            //need login ?
            return isNeedLogin(uri.toString())
                    ? new Intent[]{new Intent(context, LoginActivity.class), route}
                    : new Intent[]{route};

        } else if (uri.getScheme().equalsIgnoreCase("jinjimiapp")
            && uri.getHost().equals(RouterConstants.ROUTER_LOAD_WEB_PAGE)) {
            route = new Intent(context, WebActivity.class);
            route.putExtra(BundleKey.URL, uri.toString());
            return new Intent[]{route};
        }

        return null;
    }

    /**
     * 判断是否需要登录
     *
     * @param notification
     * @return
     */
    public static boolean isNeedLogin(PushDTO notification) {

        String url = notification.getUrl();

        if (isNativeUrl(url)) {

            URI parsedUri = URLUtil.create(url);
            if (parsedUri == null)
                return false;

            String nativeUrl = parsedUri.getHost() + parsedUri.getPath();
            if (nativeUrl.endsWith(File.separator))
                nativeUrl = nativeUrl.substring(0, nativeUrl.length() - 1);

            return RouterService.LIMIT_TABLE.contains(nativeUrl)
                    && !AccountManager.getInstance().isLogin();
        } else {
            return (url.contains(RouterService.URL_LIMIT) || notification.getLimit() == 1)
                    && !AccountManager.getInstance().isLogin();
        }
    }

    /**
     * 是否是原生界面的URL
     * <p/>
     * true app原生URL 打开原生界面
     * <p/>
     * false 网络地址,通过网页打开地址
     *
     * @param url
     * @return
     */
    public static boolean isNativeUrl(String url) {
        if (StringUtils.isEmpty(url)) {
            return false;
        }

        return url.startsWith(RouterService.ROUTER_HEADER)
                || url.startsWith(RouterService.ROUTER_HEADER_SHORT);
    }

    private static Intent getNativeIntent(Context context, URI uri) {

        String[] route = getRoute(uri);

        if (route != null) {

            Intent intent = new Intent();
            intent.setClassName(context.getPackageName(), route[0]);

            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            if (!TextUtils.isEmpty(route[1])) {
                Map<String, String> params = urlToParamsMap(route[1]);
                if (params != null) {
                    for (String name : params.keySet()) {
                        intent.putExtra(name, params.get(name));
                    }
                }
            }

            return intent;
        }

        return null;
    }

    private static String[] getRoute(URI uri) {

        String path = uri.getPath();

        String key = uri.getHost() + (path.endsWith(File.separator) ? path.substring(0, path.length() - 1) : path);

        Object route = RouterService.ROUTER_TABLE.get(key);

        if (route instanceof DirectRoute) {
            //递归查询

            String directURL = URLUtil.appendParam(
                    RouterConstants.getNativeRouter(((DirectRoute) route).path),
                    URLUtil.getParams(uri.toString())
            );

            return getRoute(URLUtil.create(directURL));
        }

        if (route instanceof String) {
            return new String[]{(String) route, uri.toString()};
        }

        return null;
    }

    public static boolean isNeedLogin(String url) {

        if (isNativeUrl(url)) {

            URI parsedUri = URLUtil.create(url);
            if (parsedUri == null)
                return false;

            String nativeUrl = parsedUri.getHost() + parsedUri.getPath();
            if (nativeUrl.endsWith(File.separator))
                nativeUrl = nativeUrl.substring(0, nativeUrl.length() - 1);

            return RouterService.LIMIT_TABLE.contains(nativeUrl)
                    && !AccountManager.getInstance().isLogin();
        } else {
            return (url.contains(RouterService.URL_LIMIT))
                    && !AccountManager.getInstance().isLogin();
        }
    }

    /**
     * 获取URL上的参数
     *
     * @param url
     * @return
     */
    public static Map<String, String> urlToParamsMap(String url) {
        if (StringUtils.isEmpty(url)) {
            return null;
        }

        try {
            if (!URLUtil.findParams(url)) {
                url = URLUtil.decode(url);
            }

            Map<String, String> formatParams = new HashMap<>();
            Map<String, String> params = URLUtil.getParams(url);

            if (params != null) {
                for (String key : params.keySet()) {
                    String valueDecode = URLUtil.decode(params.get(key));
                    formatParams.put(key, valueDecode);
                }
            }

            return formatParams;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 检查当前url是否支持
     * <p/>
     * 合法的url包涵以下类型:
     * 1.HTTP/HTTPS (&& 域名在白名单)
     * 2.Native Link
     *
     * @param url
     * @return
     */
    public static boolean isAllowedUrl(String url) {
        return isNativeUrl(url) || Uri.parse(url).isAbsolute();
    }

    /* 判断当前路由是否需要登陆且已经登陆 */
    public static boolean isNeedLoginAndHasLogin(String url) {
        if (isNativeUrl(url)) {
            URI parsedUri = URLUtil.create(url);
            if (parsedUri == null) {
                return false;
            }

            String nativeurl = parsedUri.getHost() + parsedUri.getPath();
            if (nativeurl.endsWith(File.separator))
                nativeurl = nativeurl.substring(0, nativeurl.length() - 1);

            if (RouterService.LIMIT_TABLE.contains(nativeurl)) {
                return AccountManager.getInstance().isLogin();
            } else {
                return true;
            }
        } else {
            if (url.contains(RouterService.URL_LIMIT)) {
                return AccountManager.getInstance().isLogin();

            } else {
                return true;
            }
        }
    }

    public static String newNativeUrl(String url) {
        if(!TextUtils.isEmpty(url)
                && !url.startsWith(RouterService.ROUTER_HEADER)
                && !url.startsWith(RouterService.ROUTER_HEADER_SHORT)
                && !url.startsWith("http://")
                && !url.startsWith("https://")){
            return RouterService.ROUTER_HEADER_SHORT + url;
        }
        return url;
    }

    public static void toUrl(Context context, String url) {
        toUrl(context, url, null);
    }

    public static void toUrl(Context context, String url, Bundle params) {
        Router.create(context, newNativeUrl(url)).open();
    }
}